package main

import (
	"sync"
	"fmt"
)

/*
func Gopool() {
	start := time.Now()
	wg := new(sync.WaitGroup)
	data := make(chan int, 100)

	for i := 0; i < 8000; i++ {
		wg.Add(1)
		go func(n int) {
			defer wg.Done()
			for i = range data {
				fmt.Println("goroutine:", n, i)
			}
		}(i)
	}

	for i := 0; i < 10000; i++ {
		data <- i
	}
	close(data)
	wg.Wait()
	end := time.Now()
	fmt.Println(end.Sub(start))
}

func Nopool() {
	start := time.Now()
	wg := new(sync.WaitGroup)

	for i := 0; i < 10000; i++ {
		wg.Add(1)
		go func(n int) {
			defer wg.Done()
			fmt.Println("goroutine", n)
		}(i)
	}
	wg.Wait()

	end := time.Now()
	fmt.Println(end.Sub(start))
}


func main()  {
	Gopool()
	//Nopool()
}*/

type worker struct {
	Func func()
}

func main() {
	var wg sync.WaitGroup

	channels := make(chan worker, 10)

	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for ch := range channels {
				//reflect.ValueOf(ch.Func).Call(ch.Args)
				ch.Func()
			}
		}()
	}

	for i := 0; i < 10; i++ {
		j := i
		wk := worker{
			Func: func() {
				fmt.Println(j + j)
			},
		}
		channels <- wk
	}
	close(channels)
	wg.Wait()
}